//$Id$

package builders;

/**
 * This class facilitates the ATD. Actual comparison of returned output + expected output will be done here
 * 
 * @author Yuling
 */
public class TestCase {

	private String command;
	private String[] temp;
	private boolean testPassed = false;
	private String gameStateStatus;
	private String expectedOutput;

	/**
	 * Creation of a testCase
	 * @param command	the GameMode in Message class
	 * @param testCase  the String[] args in a Message class
	 * @param expectedOutput expectedOutput to check with
	 */
	public TestCase(String command, String testCase, String expectedOutput){
		this.command = command;
		split(testCase);
		this.expectedOutput = expectedOutput;
	}

	/**
	 * private method to split up into String[] args
	 * @param testCase
	 */
	private void split(String testCase) {
		String delimiter = " ";
		if (testCase != null){
			temp = testCase.split(delimiter);
		}
	}

	/**
	 * Translation of String to actual GameMode
	 * @param gameMode
	 * @return           the actual GameMode if it can be found, null otherwise
	 */
	private GameState.GameMode getGameMode(String gameMode){
		if (gameMode.equals("SPLASH_SCREEN")){
			return GameState.GameMode.SPLASH_SCREEN;
		} else if (gameMode.equals("NEW_GAME")){
			return GameState.GameMode.NEW_GAME;
		} else if (gameMode.equals("INITIALIZE")){
			return GameState.GameMode.INITIALIZE;
		} else if (gameMode.equals("ROLL_DIE")){
			return GameState.GameMode.ROLL_DIE;
		} else if (gameMode.equals("SET_DIE_ROLL")){ // ATD to normally call this method instead of ROLL_DIE, in order to remove "randomness"
			return GameState.GameMode.SET_DIE_ROLL;
		} else if (gameMode.equals("MOVE_PIECE")){
			return GameState.GameMode.MOVE_PIECE;
		} else if (gameMode.equals("TILE_RESULTS")){
			return GameState.GameMode.TILE_RESULTS;
		} else if (gameMode.equals("END_TURN")){
			return GameState.GameMode.END_TURN;
		} else if (gameMode.equals("BUILD")){
			return GameState.GameMode.BUILD;
		} else if (gameMode.equals("END_GAME")){
			return GameState.GameMode.END_GAME;
		} else if (gameMode.equals("LOAD_GAME")){
			return GameState.GameMode.LOAD_GAME;
		} else if (gameMode.equals("SAVE_GAME")){
			return GameState.GameMode.SAVE_GAME;
		} else if (gameMode.equals("RESUME")){
			return GameState.GameMode.RESUME;
		} else if (gameMode.equals("ERROR")){
			return GameState.GameMode.ERROR;
		}
		return null;
	}

	/**
	 * Making of new Message object, so that Logic can execute
	 * @return the Message object for Logic to execute
	 */
	public Message getMessageObject(){
		return new Message(getGameMode(command), temp);
	}

	/**
	 * Checking of expectedOutput with actual gameState that is returned
	 * @param gameState
	 */
	public void verifyResult(GameState gameState) {
		// TODO Auto-generated method stub
		this.gameStateStatus = getGameState(gameState);
		if (gameStateStatus.equals(expectedOutput)){
			this.testPassed = true;
		}
	}

	/**
	 * Passes back result of checking
	 * @return
	 */
	public boolean result(){
		return testPassed;
	}

	/**
	 * Getter of gameStateStatus (not expectedOutput, but actualOutput)
	 * @return
	 */
	public String getGameStateStatus () {
		return this.gameStateStatus;
	}

	// for debugging purposes
	/*public void printResults() {
		// TODO Auto-generated method stub
		System.out.println(command);
		for (String s : temp){
			System.out.print(s);
		}
	}
	 */

	// things to be printed out from ATD:
	/*
	 * gameMode, output, players list, currentplayer, tilesYouCanMoveTo, movementActivityPoints, buildingsYouCanBuild, allBuildingsAvailableForBuilding
	 * tileManager, buildingManager
	 * 
	 * for each player, print out:
	 * name, homebase, pointsAccumulated, buildings owned and currentResourcesList, piecePosition (and filename for Piece) 
	 * 
	 * Logic should reset things that are not needed
	 * 
	 */
	/**
	 * Method that is used for identifying a gameState
	 */
	private String getGameState(GameState gameState) {
		String output = "";
		output += "GameMode: " + gameState.getGameMode() + "\n";
		output += "Previous GameMode: ";
		if (gameState.getPrevGameMode() != null){
			output += gameState.getPrevGameMode() + "\n";
		} else {
			output += null + "\n";
		}
		output += "Game Output: " + gameState.getOutput() + "\n";
		output += "Previous Game Output: ";
		if (gameState.getPrevOutput() != null){
			output+= gameState.getPrevOutput() + "\n";
		} else {
			output += null + "\n";
		}
		output += "Tiles that piece can move to: ";
		Boolean needsSpace = false;
		if (gameState.getTilesYouCanMoveTo() != null){
			for (int tile : gameState.getTilesYouCanMoveTo()) {
				if (needsSpace){
					output += " ";
				}
				output += tile;
				needsSpace = true;
			}
			needsSpace = false;
		} else { output += "null";}
		output += "\n";
		output += "Movement Activity Points Left: " + gameState.getMovementActivityPoints() + "\n";
		output += "Buildings that player can build: ";
		if (!gameState.getBuildingsYouCanBuild().isEmpty()) {
			for (Building b : gameState.getBuildingsYouCanBuild()){
				if (needsSpace){
					output += ", ";
				}
				output += b.getName();
				needsSpace = true;
			}
			needsSpace = false;
		} else {
			output += "null";
		}
		output += "\n";
		output += "All buildings available for building: ";
		if (!gameState.getAllBuildingsAvailableForBuilding().isEmpty()) {
			for (Building b : gameState.getAllBuildingsAvailableForBuilding()){
				if (needsSpace){
					output += ", ";
				}
				output += b.getName();
				needsSpace = true;
			}
			needsSpace = false;
		} else {
			output += "null";
		}
		output += "\n";
		Player currentPlayer = gameState.getCurrentPlayer();
		if (currentPlayer != null){
			output += "Current Player: " + gameState.getPlayerNumber(currentPlayer)+ " - " + currentPlayer.getName() + "\n";
		} else {
			output += "No Current Player\n";
		}
		output += "Players: \n";
		if (gameState.getPlayers() != null){
			Boolean needsNewLine = false;
			for (Player p : gameState.getPlayers()){
				if (needsNewLine){
					output += "\n";
				}
				output += p.getName() + " " + p.getClass().getName() + " " + p.getHomeBase() + " " + p.getPointsAccumulated() + " "+ p.getPiecePosition() +"\n";
				if (!p.getBuildingsOwned().isEmpty()){
					for (Building b : p.getBuildingsOwned()){
						if (needsSpace) {
							output += ", ";
						}
						output += b.getName();
						needsSpace = true;
					}
					needsSpace = false;
					output += "\n";
				} else {
					output += "No buildings owned\n";
				}
				for (Player.Resource r : Player.Resource.values()){
					if (needsSpace){
						output += " ";
					}
					output+= r + ": "+ p.getCurrentResourceAmount(r);
					needsSpace = true;
				}
				needsSpace = false;
				needsNewLine = true;
			}
			needsNewLine = false;
		} else {
			output += "There are no players";
		}
		return output;
	}

	/**
	 * Method for getting the expected output
	 * @return
	 */
	public String getExpectedOutput(){
		return expectedOutput;
	}

}
